const fs = require('fs');
const Koa = require('koa');
const Router = require('koa-router');
const path = require('path');
const static = require('koa-static');
const cors = require('koa2-cors');
const helmet = require('koa-helmet');
const koabody = require('koa-body');
const koaJwt = require('koa-jwt');
const { jwtSecret } = require('./utils/config');

const app = new Koa();
const router = new Router();
const host = process.env.HOST || '127.0.0.1';
const port = process.env.PORT || 5000;

// 读取静态文件
function useStatic(dirPath) {
  dirPath = dirPath || './public'
  console.log(static(path.join(__dirname, dirPath)));
  app.use(static(path.join(__dirname, dirPath)));
};

//注册路由
function useRouter(path) {
  path = path || __dirname + '/routes'
  let urls = fs.readdirSync(path)
  urls.forEach((element) => {
    const elementPath = path + '/' + element
    const stat = fs.lstatSync(elementPath);
    const isDir = stat.isDirectory();
    if (isDir) {
      // 文件夹递归注册路由
      useRouter(elementPath)
    } else {
      let module = require(elementPath)
      let routeRrefix = path.split('/routes')[1] || ''
      router.use(routeRrefix + '/' + element.replace('.js', ''), module.routes())
    }
  })
  app.use(router.routes()).use(router.allowedMethods())
};

// 中间件
function useMiddleware() {
  app.use(helmet())
  app.use(koabody({
    multipart: true,
    formidable: {
      maxFieldsSize: 20 * 1024 * 1024,
      maxFileSize: 20 * 1024 * 1024
    }
  }));
  //设置全局返回头
  app.use(cors({
    origin: ctx => ctx.header.origin,
    exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
    maxAge: 86400,
    credentials: true, // 允许携带头部验证信息
    allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'],
    allowHeaders: ['Content-Type', 'Authorization', 'Accept', 'X-Token']
  }));
  // 错误捕捉中间件
  app.use(async (ctx, next) => {
    try {
      await next();
    } catch (err) {
      console.log('--------error--------');
      console.log(ctx.request);
      console.log(err.status);
      console.log(err);
      console.log('--------errorEnd--------');
      if (err.status === 401) {
        ctx.body = {
          code: 401,
          msg: '登录失效！'
        }
        return;
      }
      ctx.body = err;
    }
  });
  // 从url、body 或者 cookie 中获取 token
  app.use(async (ctx, next) => {
    let params = Object.assign({}, ctx.request.query, ctx.request.body);
    let token = ctx.request.header && ctx.request.header.authorization ? ctx.request.header.authorization : (params.token ? params.token : null);
    if (!token) {
      token = ctx.cookies.get('token') || null;
    }
    ctx.request.header = {
      'authorization': token && token.startsWith('Bearer') ? token : "Bearer " + token
    }
    await next();
  })
  // 鉴权
  app.use(
    koaJwt({
      secret: jwtSecret
    })
    // 放行的路由
    .unless({
      path: ['/', /^\/app/, '/admin/user/login', '/favicon.ico']
    })
  );
};

async function start() {
  useMiddleware();
  useStatic();
  useRouter();
  app.listen(port, host);
  console.log(`Server listening on http://${host}:${port}`);
};
start();